package com.telit.firecommand.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSON;
import com.telit.common.constant.MsgIdentificationConstants;
import com.telit.common.entity.DataReturn;
import com.telit.common.util.DateUtils;
import com.telit.common.util.JwtTokenUtils;
import com.telit.communicate.dto.SendMessageDTO;
import com.telit.communicate.feign.RemoteCommunicateService;
import com.telit.firecommand.dao.CommAlarmPromptDao;
import com.telit.firecommand.dao.CommAlarmPromptJobDao;
import com.telit.firecommand.entity.CommAlarmPromptJob;
import com.telit.firecommand.service.CommAlarmPromptService;
import com.telit.firecommand.service.FireAdminService;
import com.telit.firecommand.service.FireAlarmPromptTaskService;
import com.telit.firecommand.vo.CommAlarmPromptVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;


/**
 * Create by Chencf 2022/10/29
 */
@Slf4j
@Service
public class FireAlarmPromptTaskServiceImpl implements FireAlarmPromptTaskService {

    @Autowired
    private CommAlarmPromptJobDao commAlarmPromptJobDao;

    @Autowired
    private CommAlarmPromptDao commAlarmPromptDao;

    @Autowired
    private RemoteCommunicateService communicateFeignClient;

    @Autowired
    private FireAdminService fireAdminService;

    @Autowired
    private CommAlarmPromptService commAlarmPromptService;

    @Override
    public void warningTone() {

        //查询用户设置的报警时间
        CommAlarmPromptVO alarmPrompt = commAlarmPromptService.getAlarmPrompt();
        if (Objects.nonNull(alarmPrompt)) {
            Long shiTime = Long.parseLong(alarmPrompt.getShiPrompt()) * 60000;
            Long xiangTime = Long.parseLong(alarmPrompt.getXiangPrompt()) * 60000;
            //判断comm_alarm_prompt_job表中的alarm_time和现在时间对比是否超过指定设置时间
            //查询comm_alarm_prompt_job表里面所有的信息
            // 2022-12-01优化查询项，将提醒改变逻辑
            List<CommAlarmPromptJob> commAlarmPromptJobList = commAlarmPromptJobDao.selectAllPrompt();
            List<String> shiCode = new ArrayList<>();
            List<String> shenCode = new ArrayList<>();

            for (CommAlarmPromptJob commAlarmPromptJob : commAlarmPromptJobList) {
                //判断时间是否超过指定时间
                if (commAlarmPromptJob.getStatus() == 1 && StringUtils.isNotBlank(commAlarmPromptJob.getDistrictCode())
                        && commAlarmPromptJob.getDistrictCode().length() > 0) {
                    long xiangintervalBetween = DateUtils.getIntervalBetween(commAlarmPromptJob.getAlarmTime(),
                            new Date());
                    long shiintervalBetween = DateUtils.getIntervalBetween(commAlarmPromptJob.getAlarmTime(),
                            new Date());
                    if (xiangintervalBetween > xiangTime && (commAlarmPromptJob.getShiIsRemind() == 0)) {
                        //需要提示的市级行政区划code集合
                        shiCode.add(commAlarmPromptJob.getDistrictCode().substring(0, 4));
                        //说明县超过时间没有接警 给市提示
                        //setMsg(commAlarmPromptJob);
                        //将超过报警的全部置为1
                        commAlarmPromptJobDao.updateShiByFireId(commAlarmPromptJob.getFireId());
                    }
                    if (shiintervalBetween > (shiTime + xiangTime) && (commAlarmPromptJob.getShenIsRemind() == 0)) {
                        shenCode.add(commAlarmPromptJob.getDistrictCode().substring(0, 2));
                        //说明市没有接警  给省提示
                        commAlarmPromptJob.setDistrictCode(commAlarmPromptJob.getDistrictCode().substring(0, 2));
                        //setMsg(commAlarmPromptJob);
                        //将超过报警的全部置为1
                        commAlarmPromptJobDao.updateShenByFireId(commAlarmPromptJob.getFireId());
                    }
                }
            }
            Map<String, Long> shiSocker = shiCode.stream().collect(
                    Collectors.groupingBy(k -> k, Collectors.counting()));
            Map<String, Long> shenSocker = shenCode.stream().collect(
                    Collectors.groupingBy(k -> k, Collectors.counting()));
            long t0 = System.currentTimeMillis();

            //因为目前避免不了频繁调用scoker  上面这样做法可以避免频繁调用pt-upms服务
            //获取所有的市code
            Set<String> codeshi = shiSocker.keySet();
            for (String code : codeshi) {
                final List<String> fireMangerIdList = CollUtil.<String>newArrayList();
                //根据code查询  查询当前级别的人员id
                //根据code查询
                List<String> strings = fireAdminService.fireMangerIdListByDistrictCodeLevel(code);
                fireMangerIdList.addAll(strings);
                //拿到需要对相应的人发送多少次提示，
                //逻辑是可能有n个火情都在同一行政区划中，恰巧这n给火情超过时间都没有进行接警，按照现有的思路可能需要发送n调socker信息
                if (fireMangerIdList != null && fireMangerIdList.size() > 0) {
                    Integer count = Integer.parseInt(shiSocker.get(code).toString());
                    for (int i = 0; i < count; i++) {
                        buildMsg(fireMangerIdList, code, alarmPrompt.getMediaUrl());
                    }
                }

            }

            Set<String> codeshen = shenSocker.keySet();
            for (String code : codeshen) {
                final List<String> fireMangerIdList = CollUtil.<String>newArrayList();
                //根据code查询
                List<String> strings = fireAdminService.fireMangerIdListByDistrictCodeLevel(code);
                fireMangerIdList.addAll(strings);
                //拿到需要对相应的人发送多少次提示，
                //逻辑是可能有n个火情都在同一行政区划中，恰巧这n给火情超过时间都没有进行接警，按照现有的思路可能需要发送n调socker信息
                if (fireMangerIdList != null && fireMangerIdList.size() > 0) {
                    Integer count = Integer.parseInt(shenSocker.get(code).toString());
                    for (int i = 0; i < count; i++) {
                        buildMsg(fireMangerIdList, code, alarmPrompt.getMediaUrl());
                    }
                }
            }
            long t1 = System.currentTimeMillis();
            log.info("执行socker全部完成, 共耗时:{}", (t1 - t0));
        }

    }

    private void buildMsg(List<String> fireMangerIdList, String code, String mediaUrl) {
        CommAlarmPromptJob commAlarmPromptJob = new CommAlarmPromptJob();
        commAlarmPromptJob.setAreaCode(code);
        commAlarmPromptJob.setMediaUrl(mediaUrl);
        SendMessageDTO wsDto = new SendMessageDTO("WEBWITHINUSERID", Convert.toStrArray(fireMangerIdList),
                JSON.toJSONString(DataReturn.ok(MsgIdentificationConstants.FIRE_WRANING, commAlarmPromptJob)));
        try {
            final DataReturn dr = communicateFeignClient.sendMsg(wsDto);
        } catch (Exception e) {
            log.error("微服务内部错误：websocket推送失败!msg:[{}],dr:[{}]", e.getMessage());
        }
    }


    private void setMsg(CommAlarmPromptJob commAlarmPromptJob) {
        final SendMessageDTO wsDto = buildDtoForWebSocket(commAlarmPromptJob);
        try {
            final DataReturn dr = communicateFeignClient.sendMsg(wsDto);
        } catch (Exception e) {
            log.error("微服务内部错误：websocket推送失败!msg:[{}],dr:[{}]", e.getMessage());
        }
    }

    /**
     * 构造websocket 推送对象
     *
     * @return 构造的dto对象
     */
    private SendMessageDTO buildDtoForWebSocket(CommAlarmPromptJob commAlarmPromptJob) {
        //根据转交下发流转的待处理人的行政区划code查询对应的账号id集合
        final List<String> fireMangerIdList = CollUtil.<String>newArrayList();
        if (commAlarmPromptJob.getDistrictCode() != null) {
            // todo 根据行政区划查询当前登录人员的id集合
            fireMangerIdList.addAll(
                    fireAdminService.fireMangerIdListByDistrictCode(commAlarmPromptJob.getDistrictCode()));
        } else {
            fireMangerIdList.addAll(fireAdminService.fireMangerIdList());
        }
        //将自己排除
        if (fireMangerIdList != null && fireMangerIdList.size() > 0) {
            Iterator<String> iterator = fireMangerIdList.iterator();
            while (iterator.hasNext()) {
                if (iterator.next().equals(JwtTokenUtils.getId())) {
                    iterator.remove();
                }
            }
        }

        if (fireMangerIdList != null && fireMangerIdList.size() > 0) {
            //构造消息体
            return new SendMessageDTO("WEBWITHINUSERID", Convert.toStrArray(fireMangerIdList),
                    JSON.toJSONString(DataReturn.ok(MsgIdentificationConstants.FIRE_WRANING, commAlarmPromptJob)));
        } else {
            return null;
        }
    }

}
